// This view component contains purely presentational code.

import React, { createRef } from 'react';
import PropTypes from 'prop-types';
import { matchPath } from 'react-router';

import noop from 'lodash/noop';
import get from 'lodash/get';
import { Link } from 'react-router-dom';
import { injectIntl } from 'react-intl';
import { CalloutContext, IfPermission, IntlConsumer } from '@folio/stripes/core';
import {
  Button,
  HasCommand,
  Icon,
  MultiColumnList,
  Pane,
  PaneMenu,
  Paneset,
  SearchField,
  SRStatus,
} from '@folio/stripes/components';

import {
  CollapseFilterPaneButton,
  ExpandFilterPaneButton,
  SearchAndSortNoResultsMessage as NoResultsMessage,
  SearchAndSortQuery,
} from '@folio/stripes/smart-components';

import { statusFilter, storageFilter, BASE_PAHT } from '../../constants';
import { getOptionsLable } from '../../utils';

import Filters from './Filters';

import css from './BookInStorageSearch.css';

class BookInStorageSearch extends React.Component {
    static propTypes = {
      children: PropTypes.node,
      contentRef: PropTypes.object,
      filterConfig: PropTypes.arrayOf(PropTypes.object),
      history: PropTypes.object.isRequired,
      idPrefix: PropTypes.string,
      initialSearch: PropTypes.string,
      intl: PropTypes.object.isRequired,
      location: PropTypes.object.isRequired,
      match: PropTypes.object.isRequired,
      onComponentWillUnmount: PropTypes.func,
      onNeedMoreData: PropTypes.func.isRequired,
      queryGetter: PropTypes.func,
      querySetter: PropTypes.func,
      resources: PropTypes.shape({
        records: PropTypes.object,
        patronGroups: PropTypes.object,
        departments: PropTypes.object,
      }).isRequired,
      mutator: PropTypes.shape({
        loans: PropTypes.object,
        resultOffset: PropTypes.shape({
          replace: PropTypes.func.isRequired,
        }),
      }).isRequired,
      source: PropTypes.object,
      visibleColumns: PropTypes.arrayOf(PropTypes.string),
    }

    static defaultProps = {
      idPrefix: 'bookInStorages-',
      visibleColumns: ['inDate', 'bookseller', 'beginBarcode', 'endBarcode', 'totality', 'yearFunding', 'storage', 'colourCode', 'status', 'remark'],
    };

    static contextType = CalloutContext;

    constructor(props) {
      super(props);
      this.state = {
        filterPaneIsVisible: true,
        selectedId: null,
        searchPending: false,
      };

      this.resultsPaneTitleRef = createRef();
      this.SRStatusRef = createRef();
    }

    static getDerivedStateFromProps(props) {
      const urlParams = matchPath(props.location.pathname, { path: `${BASE_PAHT}/preview/:id` });
      return {
        selectedId: urlParams ? urlParams.params.id : null,
      };
    }

    componentDidMount() {
      this._mounted = true;
    }

    componentDidUpdate(prevProps) {
      if (
        this.state.searchPending &&
            prevProps.resources.records &&
            prevProps.resources.records.isPending &&
            !this.props.resources.records.isPending) {
        this.onSearchComplete(this.props.resources.records);
      }
    }

    componentWillUnmount() {
      this._mounted = false;
    }

    onSearchComplete = records => {
      const { intl } = this.props;
      const headerEl = this.resultsPaneTitleRef.current;
      const resultsCount = get(records, 'other.totalRecords', 0);
      const hasResults = !!resultsCount;

      this.setState({ searchPending: false });

      // Announce the results for screen readers
      this.SRStatusRef.current.sendMessage('共返回{resultsCount}条记录');

      // Focus the pane header if we have results to minimize tabbing distance
      if (hasResults && headerEl) {
        headerEl.focus();
      }
    }

    toggleFilterPane = () => {
      this.setState(curState => ({
        filterPaneIsVisible: !curState.filterPaneIsVisible,
      }));
    }
    // now generates both overdue and claims returned reports

    getActionMenu = ({ onToggle }) => (
      <>
        <IfPermission perm="bookInStorages.item.post,perms.bookInStorages.item.post">
          <PaneMenu>
            <Button
              id="clickable-new-bookinstorage"
              aria-label="新增"
              to={`${BASE_PAHT}/create${this.props.location.search}`}
              buttonStyle="dropdownItem"
              marginBottom0
            >
                        新增
            </Button>
          </PaneMenu>
        </IfPermission>
      </>
    );

    renderResultsFirstMenu(filters) {
      const { filterPaneIsVisible } = this.state;
      const filterCount = filters.string !== '' ? filters.string.split(',').length : 0;

      if (filterPaneIsVisible) {
        return null;
      }

      return (
        <PaneMenu>
          <ExpandFilterPaneButton
            filterCount={filterCount}
            onClick={this.toggleFilterPane}
          />
        </PaneMenu>
      );
    }

    getRowURL(id) {
      const {
        match: { path },
        location: { search },
      } = this.props;

      return `${path}/preview/${id}${search}`;
    }

    // custom row formatter to wrap rows in anchor tags.
    anchoredRowFormatter = (row) => {
      const {
        rowIndex,
        rowClass,
        rowData,
        cells,
        rowProps,
        labelStrings
      } = row;

      return (
        <div
          key={`row-${rowIndex}`}
        >
          <Link
            to={this.getRowURL(rowData.id)}
            data-label={labelStrings && labelStrings.join('...')}
            className={rowClass}
            {...rowProps}
          >
            {cells}
          </Link>
        </div>
      );
    };

    rowUpdater = (rowData) => {
      const { resources: { patronGroups } } = this.props;
      const groupObj = patronGroups ? patronGroups.records.filter(g => g.id === rowData.patronGroup)[0] : null;
      return groupObj ? groupObj.group : null;
    }

    goToNew = () => {
      const { history } = this.props;
      history.push(`${BASE_PAHT}/create`);
    }

    shortcuts = [
      {
        name: 'new',
        handler: this.goToNew,
      },
    ];

    isSelected = ({ item }) => item.id === this.state.selectedId;

    handleSubmit = (e, onSubmit) => {
      this.setState({
        searchPending: true,
      });

      onSubmit(e);
    }

    render() {
      const {
        onComponentWillUnmount,
        idPrefix,
        visibleColumns,
        queryGetter,
        querySetter,
        initialSearch,
        source,
        onNeedMoreData,
        resources,
        contentRef,
        mutator: { resultOffset },
      } = this.props;

      const bookInStorages = get(resources, 'records.records', []);
      const patronGroups = (resources.patronGroups || {}).records || [];
      const query = queryGetter ? queryGetter() || {} : {};
      const count = source ? source.totalCount() : 0;
      const sortOrder = query.sort || '';
      const resultsStatusMessage = source ? (
        <div>
          <NoResultsMessage
            source={source}
            searchTerm={query.query || ''}
            filterPaneIsVisible
            toggleFilterPane={noop}
          />
        </div>) : 'no source yet';

      let resultPaneSub = '输入搜索条件开始搜索';
      if (source && source.loaded()) {
        resultPaneSub = `找到${count}条记录`;
      }

      const resultsFormatter = {
        inDate: bookInStorage => bookInStorage.inDate.substr(0, 10),
        bookseller: bookInStorage => bookInStorage.bookseller,
        beginBarcode: bookInStorage => bookInStorage.beginBarcode,
        endBarcode: bookInStorage => bookInStorage.endBarcode,
        totality: bookInStorage => bookInStorage.totality,
        yearFunding: bookInStorage => bookInStorage.yearFunding,
        storage: bookInStorage => getOptionsLable(storageFilter, bookInStorage.storage),
        status: bookInStorage => getOptionsLable(statusFilter, bookInStorage.status),
      };

      return (
        <HasCommand commands={this.shortcuts}>
          <div data-test-bookinstorage-instances ref={contentRef}>
            <SearchAndSortQuery
              querySetter={querySetter}
              queryGetter={queryGetter}
              onComponentWillUnmount={onComponentWillUnmount}
              initialSearch={initialSearch}
              initialSearchState={{ qindex: '', query: '' }}
            >
              {
                            ({
                              searchValue,
                              getSearchHandlers,
                              onSubmitSearch,
                              onSort,
                              getFilterHandlers,
                              activeFilters,
                              filterChanged,
                              searchChanged,
                              resetAll,
                            }) => {
                              return (
                                <IntlConsumer>
                                  {intl => (
                                    <Paneset id={`${idPrefix}-paneset`}>
                                      {this.state.filterPaneIsVisible &&
                                        <Pane
                                          defaultWidth="22%"
                                          paneTitle="馆藏入库查询"
                                          lastMenu={
                                            <PaneMenu>
                                              <CollapseFilterPaneButton onClick={this.toggleFilterPane} />
                                            </PaneMenu>
                                                    }
                                        >
                                          <form onSubmit={e => this.handleSubmit(e, onSubmitSearch)}>
                                            <SRStatus ref={this.SRStatusRef} />
                                            <div className={css.searchGroupWrap}>

                                              <SearchField
                                                aria-label="查询"
                                                autoFocus
                                                autoComplete="off"
                                                name="query"
                                                id="input-bookInStorage-search"
                                                className={css.searchField}
                                                onChange={(e) => {
                                                  if (e.target.value) {
                                                    getSearchHandlers().query(e);
                                                  } else {
                                                    getSearchHandlers().reset();
                                                  }
                                                }}
                                                value={searchValue.query}
                                                marginBottom0
                                                data-test-bookInStorage-search-input
                                              />
                                              <Button
                                                id="submit-bookInStorage-search"
                                                type="submit"
                                                buttonStyle="primary"
                                                fullWidth
                                                marginBottom0
                                                disabled={(!searchValue.query || searchValue.query === '')}
                                                data-test-user-search-submit
                                              >
                                                                查询
                                              </Button>
                                            </div>
                                            <div className={css.resetButtonWrap}>
                                              <Button
                                                buttonStyle="none"
                                                id="clickable-reset-all"
                                                disabled={!(filterChanged || searchChanged)}
                                                fullWidth
                                                onClick={resetAll}
                                              >
                                                <Icon icon="times-circle-solid">
                                                                    清除
                                                </Icon>
                                              </Button>
                                            </div>
                                            <Filters
                                              activeFilters={activeFilters.state}
                                              resources={resources}
                                              onChangeHandlers={getFilterHandlers()}
                                              resultOffset={resultOffset}
                                            />
                                          </form>
                                        </Pane>
                                                }
                                      <Pane
                                        id={`${idPrefix}-results-pane`}
                                        firstMenu={this.renderResultsFirstMenu(activeFilters)}
                                        paneTitleRef={this.resultsPaneTitleRef}
                                        paneTitle="馆藏入库查询结果"
                                        paneSub={resultPaneSub}
                                        defaultWidth="fill"
                                        actionMenu={this.getActionMenu}
                                        padContent={false}
                                        noOverflow
                                      >
                                        <MultiColumnList
                                          id="list-users"
                                          visibleColumns={visibleColumns}
                                          rowUpdater={this.rowUpdater}
                                          contentData={bookInStorages}
                                          totalCount={count}
                                          columnMapping={{
                                            inDate: '入库日期',
                                            bookseller: '书商',
                                            beginBarcode: '开始条码',
                                            endBarcode: '结束条码',
                                            totality: '总册数',
                                            yearFunding: '经费年份',
                                            storage: '入库地点',
                                            colourCode: '色标',
                                            status: '状态',
                                            remark: '备注'
                                          }}
                                          formatter={resultsFormatter}
                                          rowFormatter={this.anchoredRowFormatter}
                                          onNeedMoreData={onNeedMoreData}
                                          onHeaderClick={onSort}
                                          sortOrder={sortOrder.replace(/^-/, '').replace(/,.*/, '')}
                                          sortDirection={sortOrder.startsWith('-') ? 'descending' : 'ascending'}
                                          isEmptyMessage={resultsStatusMessage}
                                          isSelected={this.isSelected}
                                          autosize
                                          virtualize
                                          hasMargin
                                          pageAmount={100}
                                          pagingType="click"
                                        />

                                      </Pane>
                                      {this.props.children}
                                    </Paneset>
                                  )}
                                </IntlConsumer>
                              );
                            }}
            </SearchAndSortQuery>
          </div>
        </HasCommand>);
    }
}

export default injectIntl(BookInStorageSearch);
